// ---------------------------------------------------------------------------
//  File:color_support.cpp
//
//  Description: Contains the main routines that generate the blended colors
//               and converts to the KML color format.
//
//  Author: golden.colorado.5280@gmail.com
//
//  Date: December 26th, 2015
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//  DEALINGS IN THE SOFTWARE.
// ---------------------------------------------------------------------------

#include "color_support.h"

using namespace std;

//Converts an ASCII hexadecimal value to unsigned int example: FF -> 255
unsigned int hex_to_int(std::string hex){
    unsigned int x;
    std::stringstream ss;
    ss << std::hex << hex;
    ss >> x;
    return x;
}
//Converts an unsigned int to an ASCII hexadecimal value example: 255 --> FF
std::string int_to_hex(unsigned int i){
    std::stringstream stream;
    stream  << std::setfill ('0') << std::setw(2) //two bytes
            << std::hex << i;
    return stream.str();
}

//Formats the RGB colors into a KML color format
std::string rgb_to_kml(RGB c){
    std::string aa = int_to_hex( (unsigned int)(c.a * 255) );
    std::string rr = int_to_hex( (unsigned int)(c.r * 255) );
    std::string gg = int_to_hex( (unsigned int)(c.g * 255) );
    std::string bb = int_to_hex( (unsigned int)(c.b * 255) );
    std::string aabbggrr = aa+bb+gg+rr;
    return aabbggrr;
}

//Converts a KML color format and extracts the RGB values
RGB kml_to_rgb(std::string aabbggrr){
    //The order of expression is aabbggrr,
    //where aa=alpha (00 to ff); bb=blue (00 to ff);
    //gg=green (00 to ff); rr=red (00 to ff).
    std::string aa = aabbggrr.substr(0,2);  //alpha
    std::string bb = aabbggrr.substr(2,2);  //blue
    std::string gg = aabbggrr.substr(4,2);  //green
    std::string rr = aabbggrr.substr(6,2);  //red

    RGB c;
    c.a = hex_to_int(aa)/256.0; //percent
    c.r = hex_to_int(rr)/256.0; //percent
    c.g = hex_to_int(gg)/256.0; //percent
    c.b = hex_to_int(bb)/256.0; //percent
    return c;
}

//Changes the opacity parameter in  the RGB structure
void set_rgb_opacity(RGB *c, float transparent){
    c->a = transparent; //percent
}

//Support function to blend two RGB colors
float blend(double a, double b, double alpha){
  return (1.f - alpha) * a + alpha * b;
}

//Takes two RGB colors and generates intermediate colors to create a smooth spectrum
RGB color_blend(const RGB *a, const RGB *b, double alpha){
  RGB x;
  x.r = blend(a->r, b->r, alpha);
  x.g = blend(a->g, b->g, alpha);
  x.b = blend(a->b, b->b, alpha);
  x.a = a->a; //retain the opacity parameter
  return x;
}

